Skip to content

feat(ui): die Auswahl wird benutzbar — Typzeile, Doppelklick, Pioniersprung (#50) - #123

Merged
cubetribe merged 2 commits into
mainfrom
feat/s22-selection-findability
Aug 29, 2026
Merged

feat(ui): die Auswahl wird benutzbar — Typzeile, Doppelklick, Pioniersprung (#50)#123
cubetribe merged 2 commits into
mainfrom
feat/s22-selection-findability

Conversation

@cubetribe

Copy link
Copy Markdown
Collaborator

Warum

Aus dem Betatest vom 09.08.2026, und die Folge ist kein Komfortproblem:

„Viele Einheiten standen auf einem Haufen. Ich konnte nicht eindeutig erkennen, was markiert war, und fand den Pionier nicht wieder."

„Weil ich den Pionier in der Gruppe nicht wiederfand, konnte ich nicht bauen."

Der Bauablauf bricht daran ab. Paket 21.5 hat die Aufstellung geliefert — die Befehlskarte schlüsselt die Auswahl nach Typ auf. Sie war nur nicht benutzbar: man sah, was markiert ist, konnte es aber nicht anfassen.

Fixes #50

Was jetzt geht

1. Die Typzeile filtert die Auswahl. Ein Klick auf „2× Lynx — 180/240 HP" reduziert die Auswahl auf genau diese Einheiten. SelectionManager.RetainRole behält dabei die Reihenfolge der Auswahl bei — der Anführer der reduzierten Auswahl ist damit dieselbe Einheit, nach der die Zeile ohnehin sortiert war. Tote Handles werden gegen den lebenden Store verworfen, dieselbe Höflichkeit wie beim Abruf einer Kontrollgruppe.

2. Doppelklick wählt alle sichtbaren Einheiten derselben Rolle. Zweiter Klick auf dieselbe Einheit innerhalb von 0,35 s. „Sichtbar" heißt im Kamerabild, nicht auf der ganzen Karte — kartenweit wäre ein anderer Befehl und würde überraschen. Shift bleibt additiv, wie bei der bestehenden Klickauswahl.

3. I springt zum nächsten unbeschäftigten Pionier und zentriert die Kamera auf ihn. Ohne das Zentrieren findet man ihn genauso wenig wie vorher. Wiederholtes Drücken tourt in aufsteigender Entitäts-Reihenfolge — der Reihenfolge des Entity-Stores selbst, also stabil und reproduzierbar — und läuft einmal um.

Was „unbeschäftigt" heißt — am Code abgelesen, nicht geraten

IdleBuilderQuery prüft fünf Marker, und die Liste ist nicht erfunden: sie ist die Räumliste des Stop-Befehls, also die Aufzählung der Simulation selbst.

  • IsMoving — ein Bewegungsauftrag
  • AttackTarget — ein Angriffsauftrag
  • HarvestFieldId und IsReturningCargo — die beiden Wirtschaftsaufträge. Ein Pionier hält die nie legitim; die Abfrage prüft sie trotzdem, denn ein Zustand, den es nicht geben sollte, muss als beschäftigt lesen und nie als freie Arbeitskraft
  • baustellenseitig: der AssignedBuilderRaw einer Baustelle — wer einer Baustelle zugewiesen ist, baut oder ist auf dem Weg dorthin

Der gemeldete blinde Fleck

Ein sechster Marker ist aus dieser Schicht nicht sichtbar, und das steht so im Code statt genähert zu werden: ein laufender Reparaturauftrag lebt in der privaten Reparaturtabelle des ConstructionSystem. Die einzige öffentliche Fläche ist schreibseitig, und der Reparatur-Tick verändert die Gesundheit des Ziels, nie den UnitState des Pioniers.

Ein Pionier, der gerade repariert, liest hier also als unbeschäftigt. Das ist eine bewusste, dokumentierte Falschantwort in genau einem gelegentlichen Zustand — kein Rateergebnis. Sie zu schließen bräuchte einen einzeiligen öffentlichen Leser in Simulation/**, und das ist außerhalb dessen, was #50 ist: Auswahl und Darstellung. Die Abfrage ist so geschnitten, dass der spätere Reparatur-Leser als eine weitere Klausel hineinpasst.

Kein Simulationseingriff

Alle Daten liegen im EntityManager. Kein neuer CommandKind, kein Snapshot-Feld, keine Regeländerung, RulesHash64 bewegt sich nicht. Der Kameraschwenk ist Präsentation und fließt in keinen Snapshot.

Nachweis

  • dotnet test tools/Nova.SimRunner.Tests -c Release: 730/730, vorher wie nachher unverändert — genau das erwartete Ergebnis, denn diese Kette kompiliert Gameplay/ und Presentation/ gar nicht mit. Sie belegt hier nur, dass nichts in die Simulation durchgeschlagen ist
  • 13 neue EditMode-Tests. Die Logik liegt bewusst in reinen, Unity-freien Funktionen (IdleBuilderQuery, SelectionManager.RetainRole / ReplaceSelection / AddRange) — dasselbe Muster, das Paket 21.5 mit CommandCardPresenter etabliert hat: was in OnGUI hängt, kann niemand testen; was daneben liegt, schon. Abgedeckt sind die Idle-Definition, die Baustellen-Zuweisung, das Touren mit Umlauf, der Einzelfall, der Leerfall, und die drei neuen SelectionManager-Wege
  • Nicht belegt: Unity stand keinem Worker zur Verfügung. Die EditMode-Tests sind geschrieben, nicht gelaufen; die OnGUI-Verdrahtung (Trefferflächen der Zeilen, EstimateHeight, IsPointerOverHud) ist gelesen, nicht geklickt. Das ist der Teil, den ein Mensch nachfahren muss — und zwar an genau den zwei Stellen, an denen es im Bestand schon einmal schiefging: eine Zeile, die sichtbar aber nicht klickbar ist, und ein Klick, der hinter dem Panel in die Welt durchschlägt

Herkunft

Gebaut von Kimi K3 als delegiertem Worker. Der Lauf ist nach 164 Turns an der Kimi-Stundenquote gescheitert — nach der Implementierung, den Tests und dem Nachweislauf, aber vor dem Bericht. Diese Beschreibung ist deshalb vom Orchestrator aus dem Diff geschrieben, nicht aus einem Workerbericht; die Arbeit selbst ist vollständig.

@cubetribe
cubetribe merged commit f3c7ecc into main Aug 29, 2026
6 checks passed
@cubetribe
cubetribe deleted the feat/s22-selection-findability branch August 29, 2026 10:42
cubetribe added a commit that referenced this pull request Aug 29, 2026
…ichte einpflegen (#124)

## Was

Der Papierkram zu einer Sitzung, in der acht Pakete auf `main` gelandet sind — plus die Berichte, die nach Core Rule 8 in den Bestand gehören und nicht in eine Sitzung.

## Sprint 21 ist abgeschlossen

Alle acht Pakete liegen auf `main`, die headless-Kette steht am Ende bei **736/736**. Der neue Ergebnisabschnitt trägt die Paket-zu-PR-Tabelle und, wichtiger, **was der Sprint über sich selbst gelernt hat**:

**R-1 war unterzählt.** Das Risiko nannte vier Stellen, an denen die kanonische Feldlage literal im Repo steht. Es sind sechs. Fünf sind mitgezogen; die sechste (`Assets/_Project/Editor/BootstrapSceneGenerator.cs:296`) liegt außerhalb der Schreibhoheit und ist heute folgenlos, weil `MapDefinitionSO` außerhalb von `Editor/` keinen Laufzeitkonsumenten hat. Als Paket 22.3 nachgezogen.

**R-2 war schlicht falsch.** Der Sprint nahm an, vier Baseline-Gruppen würden rot, und leitete daraus seine wichtigste Merge-Regel ab. **Keine einzige Baseline hat sich bewegt** — auch nicht bei einer kompletten Kartenneuschreibung samt unbegehbarem Gelände. Das ist bequem und zugleich der eigentliche Befund: die Determinismus-Baselines pinnen Wire-Formate und PRNG, aber keinen Karteninhalt. Dieselbe Lücke wie [#108](#108) bei der Ankerregel, nur größer.

**Dreimal hat ein Arbeiter angehalten statt zu raten** — falsche Prämisse in D-108, die sechste Spiegelstelle, der nicht beobachtbare Reparaturzustand eines Pioniers — und dreimal war das die wertvollere Antwort. Ein vierter Lauf, als Gegenleser angesetzt, hat in der neuen Geländequelle eine **sachlich falsche Begründung** gefunden (die Behauptung, eine einzellige Wand lecke diagonal). Sie ist rechnerisch widerlegt und vor dem Merge berichtigt worden. Genau diese Sorte Docstring hat D-108 erzeugt.

Was ausdrücklich **offen** bleibt, steht ebenfalls dort: die gespielte Runde, die Unity-Testspuren, die CI-Lücke bei der Geländetabelle, der `CostField`-Docstring, und der blinde Fleck im Erreichbarkeitstest.

## Sprint 22 ist festgeplant

Vier kleine Pakete, alle aus den Nebenbefunden von Sprint 21 und dem Umbenennungs-Inventar. Der Sprint baut bewusst kein neues System: was drin ist, ist **heute schon kaputt oder fehlend**, und niemand merkt es, weil nichts es prüft.

- **22.1** Auswahl benutzbar (#50) — bereits geliefert in [#123](#123)
- **22.2** Gate-Vertrag auf das richtige Repo (#14 Stufe 1) — bereits geliefert in [#121](#121)
- **22.3** Die sechste Feldlage-Spiegelstelle, und die Frage, warum `MapDefinitionSO` existiert, wenn es niemand liest
- **22.4** Das Gate läuft grün über zwei Assemblies, die es nicht gibt

Ein eigener Abschnitt weist **sechs autonom getroffene Entscheidungen** aus, die während der Abwesenheit des Inhabers gefallen sind — jede revidierbar, jede mit Begründung. Sie stehen dort, damit sie nicht stillschweigend Bestand bekommen. Die zwei wichtigsten: **#108 und die Reparaturzone (#55) werden hinter den Betatest verschoben**, weil das eine jeden verteilten Testbuild ungültig macht und das andere die Kampfbalance verschiebt — beides würde genau die Rückmeldung verfälschen, die der Betatest liefern soll.

## Die Berichte

Sechs Kimi-Läufe, alle mit `--out` in den Bestand geschrieben statt in eine Sitzung:

| Bericht | Inhalt |
|---|---|
| `sprint-21/06-kimi-karte-21.6-21.7.md` | die Kartenarbeit, Feldlage-Herleitung, Gelände-Entwurf, Epoch-Rechnung |
| `sprint-21/07-kimi-verifikationskette.md` | #110 und #74, plus drei Wege für Unity in der CI mit Empfehlung |
| `sprint-21/08-kimi-gegenlesen-karte.md` | die Gegenlesung: sieben Angriffsfragen, Befunde nach Schwere, Prüfliste auch dort, wo nichts gefunden wurde |
| `sprint-22/01-kimi-auswahl-findbarkeit.md` | der Lauf zu #50 — an der Stundenquote gescheitert, nachdem Code, Tests und Nachweis standen |
| `umbenennung-hashkrieg/01-kimi-inventar.md` | Vollinventar der Umbenennung nach fünf Risikoklassen, mit der Antwort auf die Kernfrage: ein Namespace-Rename kostet **keine** Regelrevision |
| `umbenennung-hashkrieg/02-kimi-gatevertrag.md` | die Stufe-1-Umsetzung, mit den neun lebenden Fundstellen außerhalb der Schreibhoheit |

Reine Doku- und Berichtsänderung. Kein Code, keine Testbewegung.
cubetribe added a commit that referenced this pull request Aug 29, 2026
## Was

Sprint 22 ist abgeschlossen — am selben Tag geschnitten und geliefert. Alle vier Pakete liegen auf `main`:

| Paket | PR |
|---|---|
| 22.1 Auswahl benutzbar (#50) | [#123](#123) |
| 22.2 Gate-Vertrag (#14 Stufe 1) | [#121](#121) |
| 22.3 Sechste Feldlage-Kopie | [#125](#125) |
| 22.4 Phantom-Assemblies | [#125](#125) |

## Der Ergebnisabschnitt hält vor allem eines fest

Beim Bauen des Wächters für 22.4 kam heraus, dass **G0-B.3 auf unberührtem `main` rot war** — `Nova.AI.Data` stand einen Rang zu hoch, wodurch die reale Kante `Nova.AI → Nova.AI.Data` als verbotene Kante innerhalb derselben Schicht galt. Gemerkt hat es niemand, weil das Gate nicht läuft.

Das ist derselbe Befund wie [#110](#110), eine Ebene tiefer. **Drei Fälle davon in zwei Sprints:** der Gate-Vertrag mit dem falschen Repo-Namen, der rote PlayMode-Test, und jetzt die Schichtenkarte. Die Gemeinsamkeit ist nicht der einzelne Fehler, sondern dass ihn jedes Mal nur ein Mensch gefunden hat, der zufällig hinsah. Das steht so im Sprintdokument, weil es die eigentliche Lehre der beiden Sprints ist.

## Ebenfalls drin

Die zwei Befunde, die als Issues rausgegangen sind, statt still im Bericht zu versauern:

- [#126](#126) — der Erreichbarkeitstest aus 21.7 sieht ein Feld unter einer Wand als erreichbar
- [#127](#127) — `MapDefinitionSO` hat keinen Laufzeitkonsumenten

Und, unverändert, was offen bleibt: **eine gespielte Runde** auf der neuen Karte, die Unity-Testspuren, und die Entscheidung über Unity in der CI.

Reine Dokumentationsänderung.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Einzelne Einheit in einer großen Gruppe finden und auswählen

1 participant